import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:full_display/common/qxp_color.dart';
import 'package:full_display/common/qxp_style.dart';
import 'package:full_display/generated/l10n.dart';
import 'package:full_display/provide/media_provider.dart';
import 'package:full_display/unit/log/log_util.dart';
import 'package:full_display/unit/screen/screen_util1.dart';
import 'package:full_display/unit/screen/screen_utility.dart';
import 'package:full_display/unit/web_socket/web_sockect_utils.dart';
import 'package:full_display/unit/widgets/widget_dialog/image_clipper.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_sliders/sliders.dart';
import 'dart:ui' as ui;

class ImageShow extends StatefulWidget {
  String url;
  Function(BuildContext context) tapAction;
  ImageShow({Key? key, required this.url, required this.tapAction})
      : super(key: key);

  @override
  State<ImageShow> createState() => _ImageShowState();
}

class _ImageShowState extends State<ImageShow> {
  late MediaVideoProvider imageData;
  static const double DEFAULT_WIDTH = 160;
  static const double DEFAULT_HEIGHT = 160;
  final GlobalKey _globalKey = GlobalKey();
  final GlobalKey _globalVideoKey = GlobalKey();
  final GlobalKey _globalLineKey = GlobalKey();
  GlobalKey cropTargetKey = GlobalKey();
  //视频的参数，宽，高，比例
  late double _width = 0.0;
  late double _height = 0.0;
  late double _x = 0.0;
  late double _y = 0.0;
  late double _ratio;

  //临时变量
  late double _tmpW;
  late double _tmpH;
  late Offset _lastOffset;

  //背景的宽高
  late double _bgW;
  late double _bgH;

  //图片的原始尺寸
  late int _imgW;
  late int _imgH;
  late ui.Image originImg;
  late ImageClipper clipper;
  bool isshowCrop = false;
  late double cropw = 200.0;
  late double croph = 200.0;
  @override
  initState() {
    super.initState();
    //一些参数的初始化
    _fun2().then((ui.Image image) {
      originImg = image;
      clipper = ImageClipper(originImg);
      isshowCrop = true;
      _imgW = image.width;
      _imgH = image.height;
      _ratio = image.width / image.height;
      if (image.width >= image.height) {
        _width = DEFAULT_WIDTH;
        _height = _width / _ratio;
      } else {
        _height = DEFAULT_HEIGHT;
        _width = _height * _ratio;
      }
      _tmpW = _width;
      _tmpH = _height;
      _x = (ScreenUtil1.screenWidth - _width) / 2.0;
      _y = (ScreenUtil1.screenHeight - 250.0.H - _height) / 2.0;
      setState(() {});
    });
  }

  Future<ui.Image> _fun2() async {
    Uint8List imageBytes = await File(widget.url).readAsBytesSync();
    ui.Codec codec = await ui.instantiateImageCodec(imageBytes);
    ui.FrameInfo frame = await codec.getNextFrame();
    return frame.image;
  }

  @override
  Widget build(BuildContext context) {
    cropTargetKey = GlobalKey();
    imageData = context.watch<MediaVideoProvider>();
    return Container(
      color: Colors.transparent,
      width: ScreenUtil1.screenWidth,
      height: ScreenUtil1.screenHeight,
      child: Column(
        children: [
          Container(
            color: Colors.transparent,
            width: ScreenUtil1.screenWidth,
            height: ScreenUtil1.screenHeight - 250.0.H,
            child: Stack(
              children: <Widget>[
                isshowCrop
                    ? RepaintBoundary(
                        key: cropTargetKey,
                        child: CustomPaint(
                          painter: clipper,
                          size: Size(cropw, croph),
                        ),
                      )
                    : Container(),
                Container(
                  key: _globalKey,
                  color: Colors.black,
                  width: double.infinity,
                  height: double.infinity,
                ),
                Positioned(
                  key: _globalVideoKey,
                  left: _x,
                  top: _y,
                  child: GestureDetector(
                    onScaleEnd: scaleEnd,
                    onScaleStart: scaleStart,
                    onScaleUpdate: scaleUpdate,
                    child: Image.file(
                      File(widget.url),
                      width: _width,
                      height: _height,
                      fit: BoxFit.contain,
                    ),
                  ),
                ),
                Center(
                  child: GestureDetector(
                    onScaleEnd: scaleEnd,
                    onScaleStart: scaleStart,
                    onScaleUpdate: scaleUpdate,
                    child: Container(
                      key: _globalLineKey,
                      width: 200,
                      height: 200,
                      color: ColorPlate.backgroundOpacity0,
                      child: DottedBorder(
                        color: Colors.white,
                        borderType: BorderType.RRect,
                        strokeWidth: 1,
                        radius: Radius.circular(100),
                        child: ClipRRect(),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
          Container(
            color: ColorPlate.background,
            height: 150.0.H,
            width: ScreenUtil1.screenWidth,
            child: Column(
              children: [
                Container(
                  height: 50.0.H,
                ),
                InkWell(
                  onTap: () {
                    cipeImageSize(widget.url, context);
                  },
                  child: Container(
                    height: 40.0.H,
                    width: ScreenUtil1.screenWidth - 40.0.W,
                    decoration: BoxDecoration(
                      gradient: const LinearGradient(
                          //渐变位置
                          begin: Alignment.topCenter, //右上
                          end: Alignment.bottomCenter, //左下
                          //渐变颜色[始点颜色, 结束颜色]
                          colors: [ColorPlate.app_blue, ColorPlate.sub_blue]),
                      borderRadius: BorderRadius.all(Radius.circular(20.0.H)),
                    ),
                    child: Center(
                      child: Text(
                        S.of(context).queding,
                        style: StandardTextStyle.textWhite16BoldStyle,
                      ),
                    ),
                  ),
                )
              ],
            ),
          )
        ],
      ),
    );
  }

  // void asp(Map m) {
  //   setState(() {
  //     _ratio = m["asp"];
  //     _videoSize = m["size"];
  //     RenderBox? renderBox1 =
  //         _globalLineKey.currentContext!.findRenderObject() as RenderBox?;
  //     var offset1 = renderBox1!.localToGlobal(Offset.zero);
  //     if (_videoSize.width >= _videoSize.height) {
  //       if (_videoSize.width >= DEFAULT_WIDTH) {
  //         _width = DEFAULT_WIDTH;
  //       }
  //       _height = _width / m["asp"];
  //       _x = offset1.dx + 20;
  //       _y = (200 - _height) / 2.0 + (offset1.dy - ScreenUtil1.statusBarHeight);
  //     } else {
  //       if (_videoSize.height >= DEFAULT_HEIGHT) {
  //         _height = DEFAULT_HEIGHT;
  //       }
  //       _width = _height * m["asp"];

  //       _x = (200 - _width) / 2.0 + offset1.dx;
  //       _y = (offset1.dy - ScreenUtil1.statusBarHeight) + 20;
  //     }
  //   });
  // }

  //计算背景的宽高
  void getBgInfo() {
    RenderObject? renderObject = _globalKey.currentContext?.findRenderObject();
    _bgW = renderObject!.paintBounds.size.width;
    _bgH = renderObject.paintBounds.size.height;
  }

//计算视频和划线的焦点
  void getvodie() {
    RenderBox? renderBox =
        _globalVideoKey.currentContext!.findRenderObject() as RenderBox?;
    var offset = renderBox!.localToGlobal(Offset.zero);
    print("renderBox=======>${offset.dx}======${offset.dy}");

    RenderBox? renderBox1 =
        _globalLineKey.currentContext!.findRenderObject() as RenderBox?;
    var offset1 = renderBox1!.localToGlobal(Offset.zero);
    print("renderBox1=======>${offset1.dx}======${offset1.dy}");
  }

  //开始缩放
  void scaleStart(ScaleStartDetails details) {
    _tmpW = _width;
    _tmpH = _height;
    _lastOffset = details.focalPoint;
    getBgInfo();
  }

  //缩放更新
  void scaleUpdate(ScaleUpdateDetails details) {
    setState(() {
      _width = _tmpW * details.scale;
      _height = _tmpH * details.scale;
      _x += (details.focalPoint.dx - _lastOffset.dx);
      _y += (details.focalPoint.dy - _lastOffset.dy);
      //边界判定，保持宽高比
      if (_width > _bgW * 2) {
        _width = _bgW * 2;
        _height = _width / _ratio;
      }
      // if (_height > _bgH) {
      //   _height = _bgH;
      //   _width = _height * _ratio;
      // }
      if (_x < -(_width - 50)) {
        _x = -(_width - 50);
      }
      if (_y < -(_height - 50)) {
        _y = -(_height - 50);
      }
      // if(_x > _bgW-_width){
      //   _x = _bgW-_width;
      // }
      if (_x > (_bgW - 50)) {
        _x = (_bgW - 50);
      }
      if (_y > (_bgH - 50)) {
        _y = (_bgH - 50);
      }
      _lastOffset = details.focalPoint;
    });
  }

  //缩放结束
  void scaleEnd(ScaleEndDetails details) {
    _tmpW = _width;
    _tmpH = _height;
    print(
        "_tmpW=========${_tmpW}====_tmpH=====${_tmpH}=====_ratio====${_ratio}");
    //边界判定，保持宽高比
    if (_tmpW > _tmpH) {
      if (_width < DEFAULT_WIDTH) {
        _width = DEFAULT_WIDTH;
        _height = _width / _ratio;
      }
    } else {
      if (_height < DEFAULT_HEIGHT) {
        _height = DEFAULT_HEIGHT;
        _width = _height * _ratio;
      }
    }
  }

//裁剪图片的尺寸
  Future<void> cipeImageSize(String path, BuildContext context) async {
    //获取路径的扩展
    final extension = p.extension(path);
    print("path=====${extension}");

    RenderObject? renderObject =
        _globalVideoKey.currentContext?.findRenderObject();
    double w = renderObject!.paintBounds.size.width;
    double h = renderObject.paintBounds.size.height;
    print("w1=======>${w}======${h}");

    double wratio = w / _imgW;
    double hratio = h / _imgH;
    print("wratio=======>${wratio}======${hratio}");

    RenderBox? renderBox =
        _globalVideoKey.currentContext!.findRenderObject() as RenderBox?;
    var offset = renderBox!.localToGlobal(Offset.zero);
    RenderBox? renderBox1 =
        _globalLineKey.currentContext!.findRenderObject() as RenderBox?;
    var offset1 = renderBox1!.localToGlobal(Offset.zero);

    print("dx=======>${offset1.dx}======${offset.dx}");
    double x = 0.0;
    double left = 0.0;
    double right_x = 0.0;
    double right_l = 0.0;
    if ((offset.dx - offset1.dx) >= 0) {
      x = 0;
      right_x = offset.dx - offset1.dx;
    } else if ((offset.dx - offset1.dx) < 0) {
      x = offset1.dx - offset.dx;
    }
    left = x / w;
    right_l = right_x / w;
    print("left=======>${left}====right_l==${right_l}");
    print(
        "dy=======>${offset1.dy}======${offset.dy}====${offset.dx - offset1.dx}");
    double y = 0.0;
    double top = 0.0;
    double bottom_y = 0.0;
    double bottom_t = 0.0;
    if ((offset.dy - offset1.dy) >= 0) {
      y = 0;
      bottom_y = offset.dy - offset1.dy;
    } else if ((offset.dy - offset1.dy) < 0) {
      y = offset1.dy - offset.dy;
      print("y=======>${y}");
    }
    // print("y=======>${y}");
    top = y / h;
    bottom_t = bottom_y / h;
    print("top=======>${top}====bottom_t==${bottom_t}");

    // double wh = 200 / wratio;
    // double videoW = wh;
    // if (videoW > _imgW) {
    //   videoW = _imgW.toDouble();
    // }
    double right = left + (200 / w) - right_l;

    // double videoH = wh;
    // if (videoH > _imgH) {
    //   videoH = _imgH.toDouble();
    // }
    double bottom = top + (200 / h) - bottom_t;
    // logD(
    // "wh=====${wh}===w=====${videoW}===h====${videoH}====w1====${_imgW}====h1===${_imgH}");
    logD(
        "x=====${left}===y=====${top}===right====${right}====bottom====${bottom}");
    clipper = ImageClipper(originImg);

    logD("cropw=====${cropw}===croph=====${croph}");
    clipper = ImageClipper(originImg,
        left: left, top: top, right: right, bottom: bottom);
    cropw = (200 - right_x);
    croph = (200 - bottom_y);
    setState(() {});
    Future.delayed(const Duration(milliseconds: 100), () async {
      RenderRepaintBoundary? boundary = cropTargetKey.currentContext!
          .findRenderObject() as RenderRepaintBoundary;
      ui.Image image =
          await boundary.toImage(pixelRatio: ScreenUtil1.pixelRatio);
      // ui.Image image = clipper.image;
      sendData(image, context);
    });
  }

  void sendData(ui.Image pickedFile, BuildContext context) {
    pickedFile
        .toByteData(
      format: ui.ImageByteFormat.png,
    )
        .then(
      (filebuffer) async {
        if (filebuffer != null) {
          final tempDir = await getApplicationDocumentsDirectory();
          File file =
              File("${tempDir.path}/image_${DateTime.now().millisecond}.png");
          if (file.existsSync()) {
            file.delete();
          }

          final bytes = filebuffer.buffer.asUint8List();
          print("bytes leng========>${bytes.length}");
          file = await file.writeAsBytes(bytes, flush: true);
          Uint8List arrayBuffer = file.readAsBytesSync();
          String base64 = base64Encode(arrayBuffer);
          print("base64 leng========>${base64}");
          int packLength = 32768;
          if (arrayBuffer != null) {
            int pack_count = (arrayBuffer.length / packLength).ceil();
            print("pack_count------->${pack_count}");
            WebSocketUtils().sendCustomMessage(66,
                content: {'type': '1', 'count': pack_count});
            if (pack_count > 0) {
              ByteData buffF = ByteData(packLength);

              for (var i = 0; i < pack_count; i++) {
                if (i == (pack_count - 1)) {
                  //最后一个数据包
                  Uint8List buffList = arrayBuffer.sublist(i * packLength);
                  buffF = ByteData.view(buffList.buffer);
                  bufferData(buffF, i, pack_count);
                } else {
                  Uint8List buffList =
                      arrayBuffer.sublist(i * packLength, (i + 1) * packLength);
                  buffF = ByteData.view(buffList.buffer);
                  bufferData(buffF, i, pack_count);
                }
              }
            }
          }
        }
        widget.tapAction(context);
      },
    );
  }

  //发送单机数据包
  void bufferData(ByteData buff, index, packCount) {
    int num = 15 + buff.lengthInBytes; //每个包的数据总长度
    Uint8List bufF = Uint8List(num);

    ByteData dataView = ByteData.view(bufF.buffer);
    var i = 0;

    dataView.setUint8(i, 0xfa);
    i++;
    dataView.setUint8(i, 0xf0);
    i++;
    dataView.setUint8(i, 66); //cmd
    i++;
    dataView.setUint8(i, 0); //number
    i++;
    dataView.setUint32(i, packCount, Endian.little); //count
    i += 4;
    dataView.setUint32(i, index, Endian.little); //index
    i += 4;
    if (index == packCount - 1) {
      dataView.setUint16(i, buff.lengthInBytes, Endian.little);
    } else {
      dataView.setUint16(i, 32768, Endian.little);
    }
    i += 2;
    ByteData dataView_data = ByteData.view(buff.buffer);
    // console.log('byteLength=', buff.byteLength);
    int k = 0;
    for (var j = 0; j < buff.lengthInBytes; j++) {
      k = j;
      dataView.setUint8(i + j, dataView_data.getUint8(j));
    }
    i = i + k + 1;
    dataView.setUint8(i, 254);
    print(bufF.lengthInBytes);

    WebSocketUtils()
        .sendCustomMessage(66, content: {"type": "2", "data": bufF});
  }
}
